﻿using System.Collections.Generic;
using System.Linq;
using PSE.Deployment.Engine.Enums;
using PSE.Deployment.Engine.Interfaces;
using PSE.Deployment.SetupBase.Configuration;
using PSE.Deployment.SetupBase.Steps;
using PSE.Deployment.Util;
using PSE.Deployment.SetupBase.Parameter.Enums;

namespace PSE.Deployment.SetupBase.Groups
{
    public class SetupChange : SetupExecutionGroup
    {
        public SetupChange(IStepGroup parent)
            : base(parent)
        {
            this.Id = "SetupChange";
        }

        protected override void AddPreStepsExecution()
        {
            base.AddPreStepsExecution();

            SetupGroup group = new SetupGroup(this, new Group() { Id = "CheckInstalationSource", Description = "Verificação da origem dos dados" });
            group.CancelBehavior = StepGroupCancelBehavior.CancelParent;
            group.Steps.Add(new CheckInstalationSource(group));
            this.Steps.Add(group);
        }

        protected override void AddStepsExecution()
        {
            base.AddStepsExecution();

            //ExecutGroups(SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Groups);

            AddSteps(SetupMode.Uninstall);

            AddSteps(SetupMode.Install);
        }

        private void AddSteps(SetupMode setupMode)
        {
            SetupMainFactory.GetInstance().Parameter.SetupMode = setupMode;

            SetupInstall setupUninstall = new SetupInstall(this);

            foreach (IStep step in setupUninstall.Steps.Where(s => s.Id != "FinalizerGroup" && s.Id != "CheckInstalationSource"))
            {
                step.Id = setupMode.ToString() + "-" + step.Id;
                step.Parent = this;
                this.Steps.Add(step);
            }
        }

        protected override void AddPosStepsExecution()
        {
            base.AddPosStepsExecution();

            SetupGroup group = new SetupGroup(this, new Group() { Id = "FinalizerGroup", Description = "Finalização da Instalação" });

            if (SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Groups.SelectDeep(g => g.SubGroups).SelectDeep(g => g.Dependencies).All(g => g.Install == false))
            {
                group.Steps.Add(new CopySetupFiles(group, group.Group,
                    new Configuration.Actions.Copy() { Id = "CopySetupFiles", Description = "Copia dos arquivos do setup" }, PSE.Deployment.SetupBase.Parameter.Enums.SetupMode.Uninstall));

                group.Steps.Add(new SaveInstallationInformation(group, group.Group,
                new Configuration.Actions.UpdateWindowsRegistry() { Id = "SaveInstallationInformation", Description = "Salva informações de instalação" }, PSE.Deployment.SetupBase.Parameter.Enums.SetupMode.Uninstall));
            }
            else
            {
                group.Steps.Add(new SaveInstallationInformation(group, group.Group,
                    new Configuration.Actions.UpdateWindowsRegistry() { Id = "SaveInstallationInformation", Description = "Salva informações de instalação" }, PSE.Deployment.SetupBase.Parameter.Enums.SetupMode.Install));
            }

            this.Steps.Add(group);
        }

        //private void ExecuteGroups(IEnumerable<Group> groups)
        //{
        //    foreach (Group group in groups)
        //    {
        //        if (group.Dependencies != null && group.Dependencies.Count > 0)
        //        {
        //            ExecuteGroups(group.Dependencies);
        //        }

        //        if (group.SubGroups != null && group.SubGroups.Count > 0)
        //        {
        //            ExecuteGroups(group.SubGroups);
        //        }

        //        if ((group.Install == null || group.Install.GetValueOrDefault()) && !group.Installed)
        //        {
        //            if (this.Steps.ToList().Find(s => s.Id == group.Id) == null)
        //                this.Steps.Add(new SetupGroup(this, group, Parameter.Enums.SetupMode.Install));
        //        }
        //        if ((group.Install.HasValue && !group.Install.Value) && group.Installed)
        //        {
        //            if (this.Steps.ToList().Find(s => s.Id == group.Id) == null)
        //                this.Steps.Add(new SetupGroup(this, group, Parameter.Enums.SetupMode.Uninstall));
        //        }
        //    }
        //}
    }
}
